package com.leo.chapter14;

/**
 * 实现了阻塞的有界缓存,基于条件队列
 * @author xuexiaolei
 * @version 2017年10月20日
 */
public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {
    protected BoundedBuffer(int capacity) {
        super(capacity);
    }

    @Override public synchronized void put(V v) throws InterruptedException {
        while (isFull()){
            wait();
        }
        doPut(v);
        notifyAll();
    }

    @Override public synchronized V take() throws InterruptedException {
        while (isEmpty()){
            wait();
        }
        V v = doTake();
        notifyAll();
        return v;
    }

    /**
     * 下面演示了一种出错情况，
     *      当上面的while换成if且isFull、isEmpty方法不同步时，就会发生buffer放入两个数据的情况
     *      所以使用条件队列的标准方法还是得遵循的
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        BoundedBuffer<Integer> buffer = new BoundedBuffer<>(1);
        new Thread(new Runnable() {
            @Override public void run() {
                try {
                    Integer item = buffer.take();
                    System.out.println(item);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override public void run() {
                try {
                    buffer.put(3);
                    System.out.println("放进去了3");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override public void run() {
                try {
                    buffer.put(4);
                    System.out.println("放进去了4");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override public void run() {
                try {
                    buffer.put(5);
                    System.out.println("放进去了5");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
